<!--
REVIEW:
列中包含fixed列的话，slot会渲染两次
-->
<style lang="less" scoped>
  .table__pagination {
    padding-top: 10px;
    text-align: right;
  }
</style>

<template>
  <div class="table__wrapper">
    <div class="table__search">
      <slot name="searchSection" />
    </div>
    <component :is="isBigdata ? 'bigdata-table' : 'el-table'" ref="table" :border="border" :show-header="showHeader" :data="tableData" :height="tableHeight" :row-class-name="rowClassName" @sort-change="sortChange" :show-summary="showSummary" :summary-method="summaryMethod" row-key="id" style="width: 100%">
      <el-table-column v-if="showExpand" fixed="left" type="expand">
        <template slot-scope="props">
          <slot name="expandRow" v-bind="{row: props.row.children}"></slot>
        </template>
      </el-table-column>
      <el-table-column v-if="hasSelection" type="selection" align="center" :reserve-selection="reserveSelection" width="50">
      </el-table-column>
      <template v-for="(columnItem, columnIndex) in tableColumn">
        <!-- 一级表头 -->
        <el-table-column v-if="columnItem.slotName" :key="columnIndex" v-bind="columnItem">
          <template slot-scope="scope">
            <slot :name="columnItem.slotName" v-bind="{row: scope.row, $index: scope.$index, option: columnItem}"></slot>
          </template>
        </el-table-column>
        <el-table-column v-else :key="columnIndex" v-bind="columnItem" :header-align="columnItem.children && columnItem.children.length > 0 ? 'center' : ''">
          <template v-if="columnItem.children">
            <template v-for="(level_1_ColumnItem, level_1_ColumnIndex) in columnItem.children">
              <!-- 二级表头 -->
              <el-table-column v-if="level_1_ColumnItem.slotName" :key="level_1_ColumnIndex" v-bind="level_1_ColumnItem">
                <template slot-scope="scope">
                  <slot :name="level_1_ColumnItem.slotName" v-bind="{row: scope.row, $index: scope.$index, option: level_1_ColumnItem}"></slot>
                </template>
              </el-table-column>
              <el-table-column v-else :key="level_1_ColumnIndex" v-bind="level_1_ColumnItem" :header-align="level_1_ColumnItem.children && level_1_ColumnItem.children.length > 0 ? 'center' : ''">
                <template v-if="level_1_ColumnItem.children">
                  <template v-for="(level_2_ColumnItem, level_2_ColumnIndex) in level_1_ColumnItem.children">
                    <!-- 三级表头 -->
                    <el-table-column v-if="level_2_ColumnItem.slotName" :key="level_2_ColumnIndex" v-bind="level_2_ColumnItem">
                      <template slot-scope="scope">
                        <slot :name="level_2_ColumnItem.slotName" v-bind="{row: scope.row, $index: scope.$index, option: level_2_ColumnItem}"></slot>
                      </template>
                    </el-table-column>
                    <el-table-column v-else :key="level_2_ColumnIndex" v-bind="level_2_ColumnItem" :header-align="level_2_ColumnItem.children && level_2_ColumnItem.children.length > 0 ? 'center' : ''">
                      <template v-if="level_2_ColumnItem.children">
                        <template v-for="(level_3_ColumnItem, level_3_ColumnIndex) in level_2_ColumnItem.children">
                          <!-- 四级表头 -->
                          <el-table-column v-if="level_3_ColumnItem.slotName" :key="level_3_ColumnIndex" v-bind="level_3_ColumnItem">
                            <template slot-scope="scope">
                              <slot :name="level_3_ColumnItem.slotName" v-bind="{row: scope.row, $index: scope.$index, option: level_3_ColumnItem}"></slot>
                            </template>
                          </el-table-column>
                          <el-table-column v-else :key="level_3_ColumnIndex" v-bind="level_3_ColumnItem" :header-align="level_3_ColumnItem.children && level_3_ColumnItem.children.length > 0 ? 'center' : ''">
                            <template v-if="level_3_ColumnItem.children">
                              <template v-for="(level_4_ColumnItem, level_4_ColumnIndex) in level_3_ColumnItem.children">
                                <!-- 五级表头 -->
                                <el-table-column v-if="level_4_ColumnItem.slotName" :key="level_4_ColumnIndex" v-bind="level_4_ColumnItem">
                                  <template slot-scope="scope">
                                    <slot :name="level_4_ColumnItem.slotName" v-bind="{row: scope.row, $index: scope.$index, option: level_4_ColumnItem}"></slot>
                                  </template>
                                </el-table-column>
                                <!-- 五级结束表头，当层表头不再支持children，支持slot -->
                                <el-table-column v-else :key="level_4_ColumnIndex" v-bind="level_4_ColumnItem"></el-table-column>
                              </template>
                            </template>
                          </el-table-column>
                        </template>
                      </template>
                    </el-table-column>
                  </template>
                </template>
              </el-table-column>
            </template>
          </template>
        </el-table-column>
      </template>
    </component>

    <el-pagination v-if="pageable" class="table__pagination" @size-change="handlePageSizeChange" :current-page.sync="tablePageInfo.page" layout="total, sizes, prev, pager, next, jumper" :page-sizes="[10, 25, 50, 100]" :total="tableDataCount"></el-pagination>
  </div>
</template>
<script>
import { addResizeListener, removeResizeListener } from '../../util/resize-event'
export default {
  name: 'simple-table',
  data () {
    return {
      tableHeight: 0
    }
  },
  props: {
    tableData: { type: Array, required: true },
    tableColumn: { type: Array, required: true },
    /** 分页信息 */
    tablePageInfo: { type: Object },
    /** 数据总数 */
    tableDataCount: { type: Number, default: 0 },
    border: { type: Boolean, default: true },
    /** 是否显示分页器 */
    pageable: { type: Boolean, default: true },
    rowClassName: { type: Function, default: () => { } },

    // 是否可勾选
    hasSelection: { type: Boolean, default: false },
    // 是否记录已勾选的记录
    reserveSelection: { type: Boolean, default: false },

    showHeader: { type: Boolean, default: true },

    showExpand: { type: Boolean, default: false },

    // 是否显示汇总
    showSummary: { type: Boolean, default: false },
    summaryMethod: { type: Function, default: () => { } },

    // 是否是大数据表格
    isBigdata: { type: Boolean, default: false }

  },
  watch: {
    /** 后端并没有反馈 page 相关数据，因此删除的时候会导致数据请求的 page 数据错误 */
    'tablePageInfo.page' (val) {
      this.handlePageCurrentChange(val)
    }
  },
  methods: {
    handleElementResize () {
      /**
             * parentElementHeight --> 父级节点高度
             * searchHeight --> 查询高度
             * paginationHeight --> 分页节点高度
             */
      let parentElementHeight = this.$el.parentElement.offsetHeight
      let searchHeight = this.$el.querySelector('.table__search').offsetHeight
      let paginationHeight = this.pageable ? this.$el.querySelector('.table__pagination').offsetHeight : 0

      // 目前仅通过是否showHeader进行判断是否为嵌套的内部表格
      if (this.showHeader) {
        this.$nextTick(() => {
          this.tableHeight = parentElementHeight - paginationHeight - searchHeight
        })
      } else {
        this.tableHeight = 'auto'
      }
    },

    /**
         * REVIEW:
         * 更改 pageSize 时，可能会触发 pageNo 跟着变化
         * 比如共15条数据，从每页显示10条第2页的时候，更改为每页显示25条时，页码会变更为1
         * 此时会触发两次 page-info-change
         */
    /** pageSize 改变 */
    handlePageSizeChange (pageSize) {
      this.$emit('page-info-change', Object.assign(this.tablePageInfo, { rows: pageSize }))
    },
    /** pageNo 改变 */
    handlePageCurrentChange (pageNo) {
      this.$emit('page-info-change', Object.assign(this.tablePageInfo, { page: pageNo }))
    },

    /** 获取已选的记录 */
    getSelections () {
      return this.$refs.table.selection
    },

    /** 清除已选记录 */
    clearSelection () {
      this.$refs.table.clearSelection()
    },

    /** 排序事件 */
    sortChange (sortInfo) {
      this.$emit('sort-change', sortInfo)
    }

  },
  mounted () {
    // 进行监听视窗大小，来使 table 高度自适应
    addResizeListener(this.$el.parentElement, this.handleElementResize)
  },
  destroyed () {
    // 移除监听事件
    removeResizeListener(this.$el.parentElement, this.handleElementResize)
  }
}
</script>
